#pragma once

#include <vex/core/contract/config.h>
#include <vex/core/contract/handle.h>

namespace vex { namespace core { namespace contract {

    /// <summary>
    /// A <code>memory_resource</code> allocates and frees chunks of memory
    /// </summary>
    struct VEX_ABSTRACT memory_resource : virtual public handle {
        /// <summary>
        /// Allocates a chunk of memory
        /// </summary>
        /// <param name="p_size">
        /// Size (in bytes) of memory chunk to be allocated 
        /// </param>
        /// <param name="p_aligment">
        /// Required alignment in bytes
        /// </param>
        virtual void* allocate(size_t p_size, size_t p_alignment = 0u, void const* p_hint = 0u) const = 0;

        /// <summary>
        /// Deallocates a chunk of memory at <paramref name="p_memory"/> which
        /// was previously allocated via <code>allocate(p_size, p_alignment)</code>.
        /// </summary>
        virtual void deallocate(void *p_memory, size_t p_size, size_t p_alignment = 0u) const = 0;

        VEX_PROTECT_CONTRACT(memory_resource);
    };

    /// <summary>
    /// A contract for something that owns a memory resource
    /// </summary>
    struct VEX_ABSTRACT memory_resource_owner {
        virtual memory_resource* get_memory_resource() const = 0;
        VEX_PROTECT_CONTRACT(memory_resource_owner);
    };
}}}